package com.huanxing.cloud.shop.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huanxing.cloud.common.core.constant.CacheConstants;
import com.huanxing.cloud.common.core.constant.CommonConstants;
import com.huanxing.cloud.common.myabtis.tenant.HxTenantContextHolder;
import com.huanxing.cloud.common.security.handler.HxBusinessException;
import com.huanxing.cloud.shop.api.entity.MobileTheme;
import com.huanxing.cloud.shop.api.entity.PageDesign;
import com.huanxing.cloud.shop.mapper.MobileThemeMapper;
import com.huanxing.cloud.shop.service.IMobileThemeService;
import lombok.RequiredArgsConstructor;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 商城移动端主题
 *
 * @author lijx
 * @since 2022/3/17 10:57
 */
@Service
@RequiredArgsConstructor
public class MobileThemeServiceImpl extends ServiceImpl<MobileThemeMapper, MobileTheme> implements IMobileThemeService {

	private final StringRedisTemplate redisTemplate;

	private final RedissonClient redissonClient;

	@Override
	public boolean updateById(MobileTheme entity) {
		this.setIsUse();
		baseMapper.updateById(entity);
		String mobileThemeKey = CacheConstants.MOBILE_THEME_CACHE + HxTenantContextHolder.getTenantId();
		redisTemplate.delete(mobileThemeKey);
		return true;
	}

	public void setIsUse() {
		MobileTheme mobileTheme = new MobileTheme();
		mobileTheme.setIsUse(CommonConstants.NO);
		super.update(mobileTheme, Wrappers.<MobileTheme>lambdaQuery().eq(MobileTheme::getIsUse, CommonConstants.YES));
	}

	@Override
	public MobileTheme getMobileTheme(String tenantId) {
		String mobileThemeKey = CacheConstants.MOBILE_THEME_CACHE + tenantId;
		// 查询缓存
		String cache = redisTemplate.opsForValue().get(mobileThemeKey);
		if (StringUtils.hasText(cache)) {
			return JSON.parseObject(cache, MobileTheme.class);
		}
		// 加锁
		RLock rLock = redissonClient.getLock(CacheConstants.MOBILE_THEME_LOCK_CACHE + tenantId);
		try {
			if (!rLock.tryLock(5, TimeUnit.SECONDS)) {
				throw new HxBusinessException("系统繁忙.请刷新重试");
			}
			// 再次检查缓存
			cache = redisTemplate.opsForValue().get(mobileThemeKey);
			if (StringUtils.hasText(cache)) {
				return JSON.parseObject(cache, MobileTheme.class);
			}
			// 查询数据库
			MobileTheme mobileTheme = baseMapper
				.selectOne(Wrappers.<MobileTheme>lambdaQuery().eq(MobileTheme::getIsUse, CommonConstants.YES));

			if (Objects.nonNull(mobileTheme)) {
				redisTemplate.opsForValue()
					.set(mobileThemeKey, JSON.toJSONString(mobileTheme), 60 * 60 * 24 * 7, TimeUnit.SECONDS);
				return mobileTheme;
			}
			else {
				redisTemplate.opsForValue()
					.set(mobileThemeKey, JSON.toJSONString(new PageDesign()), 60, TimeUnit.SECONDS);
				return null;
			}
		}
		catch (Exception e) {
			throw new HxBusinessException("系统繁忙.请刷新重试");
		}
		finally {
			rLock.unlock();
		}
	}

}
